home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / dec / cfbpmax / cfbpmax_io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-29  |  27.0 KB  |  1,163 lines

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* $Header: cfbpmax_io.c,v 1.9 89/11/29 17:09:25 keith Exp $ */
  26.  
  27. #include <stdio.h>
  28. #include <sys/types.h>
  29. #include <sys/file.h>
  30. #include <sys/time.h>
  31. #include <sys/tty.h>
  32. #include <errno.h>
  33. #include <sys/devio.h>
  34. #include <machine/pmioctl.h>
  35. #include <machine/dc7085cons.h>
  36.  
  37. #include "misc.h"
  38. #include "X.h"
  39. #define NEED_EVENTS
  40. #include "Xproto.h"
  41. #include "scrnintstr.h"
  42. #include "pixmap.h"
  43. #include "input.h"
  44. #include "cursorstr.h"
  45. #include "regionstr.h"
  46. #include "resource.h"
  47. #include "dixstruct.h"
  48.  
  49. #include "cfbpmaxcolor.h"
  50. #include "mi.h"
  51. #include "mfb.h"
  52.  
  53. void cfbpmaxQueryBestSize();
  54. Bool cfbpmaxRealizeCursor();
  55. Bool cfbpmaxUnrealizeCursor();
  56. Bool cfbpmaxDisplayCursor();
  57. void cfbpmaxRecolorCursor();
  58. Bool cfbpmaxSetCursorPosition();
  59. void cfbpmaxCursorLimits();
  60. void cfbpmaxConstrainCursor();
  61. void cfbpmaxPointerNonInterestBox();
  62. void cfbpmaxChangeKeyboardControl();
  63. void cfbpmaxChangePointerControl();
  64. void cfbpmaxClick();
  65.  
  66. extern Bool cfbScreenInit();
  67. extern void miRecolorCursor();
  68. extern void NoopDDA();
  69.  
  70. /* XXX warning following symbol is copied from pmreg.h - this will
  71.  * be fixed when the driver header files get straightened out. PK
  72.  * 17 Aug 88
  73.  */
  74. #define MOTION_BUFFER_SIZE 100
  75.  
  76. /*
  77.  * These "statics" imply there will never be more than one "pm" display and
  78.  * mouse attached to a server; otherwise, they would be in SCREEN private info.
  79.  *
  80.  * This is probably the case since the Ultrix driver does not allow one to
  81.  * open the display without also getting at the same file descriptor that
  82.  * handles the mouse and the keyboard. Most of it is merely to pass information
  83.  * to the keyboard and pointer devices. This could be done more cleanly by
  84.  * repeating the ioctl to get the PM_Info.
  85.  */
  86.  
  87. int            fdPM;
  88.  
  89. static PM_Info        *info;
  90. static pmEventQueue    *queue;
  91. static pmBox        *mbox;
  92. static pmCursor        *mouse;
  93. static int        qLimit;
  94. static int        lastEventTime;
  95. static DevicePtr    pmKeyboard;
  96. static DevicePtr    pmPointer;
  97. static int        hotX, hotY;
  98. static BoxRec        cursorRange, cursorConstraint;
  99. static int              dpix = -1, dpiy = -1, dpi = -1;
  100. static char             *blackValue = NULL, *whiteValue = NULL;
  101. static int        class = PseudoColor;
  102. static unsigned            cursColors[6]; /* 0-2 bg 3-5 fg */
  103.  
  104. #define MAX_LED 3    /* only 3 LED's can be set by user; Lock LED
  105.                is controlled by server */
  106.  
  107. #define FRAMEWIDTH      1024
  108. #define FRAMEHEIGHT     864
  109. #define DEPTH           8
  110. #define BITS_PER_CHAR   8
  111.  
  112. #ifdef VSYNCFIXED
  113. #define CURRENT_TIME    queue->timestamp_ms
  114. #else
  115. #define CURRENT_TIME    GetTimeInMillis()
  116. #endif
  117.  
  118. #define NoSuchClass -1
  119.  
  120. static int
  121. ParseClass(className)
  122.     char *    className;
  123. {
  124.     static char *names[] = {
  125.     "StaticGray", "GrayScale", "StaticColor",
  126.     "PseudoColor", "TrueColor"};
  127.     /* only the ones we support and must be in order from X.h, since
  128.      * return value depends on index into array.
  129.      */
  130.     int i;
  131.     for (i = 0; i < sizeof(names)/sizeof(char *); i++)
  132.     {
  133.     if (strcmp(names[i], className) == 0)
  134.         return i;
  135.     }
  136.     return NoSuchClass;
  137. }
  138.  
  139. static Bool
  140. commandLineMatch( argc, argv, pat, pmatch)
  141.     int         argc;           /* may NOT be changed */
  142.     char *      argv[];         /* may NOT be changed */
  143.     char *      pat;
  144. {
  145.     int         ic;
  146.  
  147.     for ( ic=0; ic<argc; ic++)
  148.         if ( strcmp( argv[ic], pat) == 0)
  149.             return TRUE;
  150.     return FALSE;
  151. }
  152.  
  153. static Bool
  154. commandLinePairMatch( argc, argv, pat, pmatch)
  155.     int         argc;           /* may NOT be changed */
  156.     char *      argv[];         /* may NOT be changed */
  157.     char *      pat;
  158.     char **     pmatch;         /* RETURN */
  159. {
  160.     int         ic;
  161.  
  162.     for ( ic=0; ic<argc; ic++)
  163.         if ( strcmp( argv[ic], pat) == 0)
  164.         {
  165.             *pmatch = argv[ ic+1];
  166.             return TRUE;
  167.     }
  168.     return FALSE;
  169. }
  170.  
  171. static void
  172. colorNameToColor( pname, pred, pgreen, pblue)
  173.     char *      pname;
  174.     u_int *     pred;
  175.     u_int *     pgreen;
  176.     u_int *     pblue;
  177. {
  178.     if ( *pname == '#')
  179.     {
  180.         pname++;                /* skip over # */
  181.         sscanf( pname, "%2x", pred);
  182.         *pred <<= 8;
  183.  
  184.         pname += 2;
  185.         sscanf( pname, "%2x", pgreen);
  186.         *pgreen <<= 8;
  187.  
  188.         pname += 2;
  189.         sscanf( pname, "%2x", pblue);
  190.         *pblue <<= 8;
  191.     }
  192.     else /* named color */
  193.     {
  194.         *pred = *pgreen = *pblue = 0; /*OsLookupColor thinks these are shorts*/
  195.         OsLookupColor( 0 /*"screen", not used*/, pname, strlen( pname),
  196.                 pred, pgreen, pblue);
  197.     }
  198. }
  199.  
  200. /* SaveScreen does blanking, so no need to worry about the interval timer */
  201.  
  202. static Bool
  203. cfbpmaxSaveScreen(pScreen, on)
  204.     ScreenPtr pScreen;
  205.     int on;
  206. {
  207.     if (on != SCREEN_SAVER_ON)
  208.     {
  209.         lastEventTime = CURRENT_TIME;    
  210.     if (ioctl(fdPM, QIOVIDEOON) < 0)
  211.         ErrorF("pmSaveScreen: failed to turn screen on.\n");
  212.     } else {
  213.     if (ioctl(fdPM, QIOVIDEOOFF) < 0)
  214.         ErrorF("pmSaveScreen: failed to turn screen off.\n");
  215.     }
  216.     return TRUE;
  217. }
  218.  
  219. Bool
  220. cfbpmaxScreenClose(index, pScreen)
  221.     int index;
  222.     ScreenPtr pScreen;
  223. {
  224.     /* This routine frees all of the dynamically allocated space associate
  225.     with a screen. */
  226.  
  227.     /* ||| XXX cfbScreenClose(pScreen); */
  228.  
  229. /* ||| Just seeing if this lets me shut down and restart clients
  230.     if(close(fdPM))
  231.     {
  232.     ErrorF("Close of fdPM yields %d\n", errno);
  233.     return(FALSE);
  234.     }
  235. */
  236.     return(TRUE);
  237. }
  238.  
  239. Bool
  240. cfbpmaxScreenInit(index, pScreen, argc, argv)
  241.     int index;
  242.     ScreenPtr pScreen;
  243.     int argc;
  244.     char **argv;
  245. {
  246.     register    PixmapPtr pPixmap;
  247.     ColormapPtr pColormap;
  248.     int        i;
  249.     static int  mapOnce = FALSE;
  250.  
  251. /* for initializing color map entries */
  252.     u_int blackred      = 0x0000;
  253.     u_int blackgreen    = 0x0000;
  254.     u_int blackblue     = 0x0000;
  255.  
  256.     u_int whitered      = 0xffff;
  257.     u_int whitegreen    = 0xffff;
  258.     u_int whiteblue     = 0xffff;
  259.  
  260.     if (mapOnce)
  261.     {
  262.     /*
  263.      * The reason you need to do this is so that when the
  264.      * the server recycles and the system is in video off
  265.      * state you need something to turn the video on.  Note
  266.      * that unlike the vaxstar you don't do a fresh open 
  267.      * and close of the device and thus the video remains
  268.      * off if you don't explicitly turn it on.
  269.      */
  270.     if (ioctl(fdPM, QIOVIDEOON) < 0)
  271.         ErrorF("pmSaveScreen: failed to turn screen on.\n");
  272.     }
  273.  
  274.     if (! mapOnce) {
  275.     if ((fdPM = open("/dev/mouse", O_RDWR | O_NDELAY, 0)) < 0)
  276.     {
  277.         ErrorF("couldn't open /dev/mouse \n");
  278.         return FALSE;
  279.     }
  280.  
  281.     if (ioctl(fdPM, QIOCGINFO, &info) < 0)
  282.     {
  283.         extern int errno;
  284.         int en = errno;
  285.         fprintf(stderr, "errno = %d, ", en);
  286.         ErrorF("error getting address of pmax screen\n");
  287.         close(fdPM);
  288.         return FALSE;
  289.     }
  290.     ioctl(fdPM, QIOKERNLOOP);
  291.  
  292.     mapOnce = TRUE;
  293.     }
  294.  
  295.     queue = &info->qe;
  296.     mouse = &info->mouse;
  297.     qLimit = queue->eSize - 1;
  298.     lastEventTime = CURRENT_TIME;
  299.  
  300.     /* discard all the current input events */
  301.     queue->eHead = queue->eTail;
  302.  
  303.     /*
  304.      * set keyclick, mouse acceleration and threshold
  305.      */
  306.     {
  307.         int        clicklevel;
  308.         char *      clickvolume;
  309.         char *      mouseAcceleration;
  310.         int         ma = 4;
  311.         char *      mouseThreshold;
  312.         int         mt = 4;
  313.         PtrCtrl     ctrl;
  314.  
  315.         if ( commandLinePairMatch( argc, argv, "c", &clickvolume))
  316.     {
  317.         sscanf( clickvolume, "%d", &clicklevel);
  318.         cfbpmaxClick(clicklevel);
  319.     }
  320.  
  321.         if ( commandLineMatch( argc, argv, "-c"))
  322.     {
  323.         cfbpmaxClick(0);
  324.     }
  325.         
  326.         /*
  327.          * calling cfbpmaxChangePointerControl here may be unclean       XXX
  328.          */
  329.     if ( commandLinePairMatch( argc, argv, "-a", &mouseAcceleration))
  330.         sscanf( mouseAcceleration, "%d", &ma);
  331.     if ( commandLinePairMatch( argc, argv, "-t", &mouseThreshold))
  332.         sscanf( mouseThreshold, "%d", &mt);
  333.     ctrl.num = ma;
  334.     ctrl.den = 1;
  335.     ctrl.threshold = mt;
  336.     cfbpmaxChangePointerControl( (DevicePtr) NULL, &ctrl);
  337.     }
  338.  
  339.  
  340.     cursorRange.x1 = -15;
  341.     cursorRange.x2 = info->max_x - 1;
  342.     cursorRange.y1 = -15;
  343.     cursorRange.y2 = info->max_y - 1;
  344.  
  345. /* XXX FRAMEWIDTH is bogus.  Don't we get this with initial IOCTL?? */
  346.  
  347.     if (dpi == -1) /* dpi has not been set */
  348.     {
  349.         if (dpix == -1) /* ie dpix has not been set */
  350.         {
  351.         if (dpiy == -1)
  352.         {
  353.             dpix = 78;
  354.             dpiy = 78;
  355.         }
  356.         else
  357.             dpix = dpiy;
  358.         }
  359.         else
  360.         { 
  361.         if (dpiy == -1)
  362.             dpiy = dpix;
  363.         }
  364.     }
  365.     else
  366.     {
  367.     dpix = dpi;
  368.     dpiy = dpi;
  369.     }
  370.  
  371.     pScreen->CloseScreen = cfbpmaxScreenClose;
  372.     pScreen->SaveScreen = cfbpmaxSaveScreen;
  373.     pScreen->RealizeCursor = cfbpmaxRealizeCursor;
  374.     pScreen->UnrealizeCursor = cfbpmaxUnrealizeCursor;
  375.     pScreen->DisplayCursor = cfbpmaxDisplayCursor;
  376.     pScreen->SetCursorPosition = cfbpmaxSetCursorPosition;
  377.     pScreen->CursorLimits = cfbpmaxCursorLimits;
  378.     pScreen->PointerNonInterestBox = cfbpmaxPointerNonInterestBox;
  379.     pScreen->ConstrainCursor = cfbpmaxConstrainCursor;
  380.     pScreen->RecolorCursor = cfbpmaxRecolorCursor;
  381.     pScreen->QueryBestSize = cfbpmaxQueryBestSize;
  382.  
  383.     pScreen->StoreColors = cfbpmaxStoreColors;
  384.     pScreen->InstallColormap = cfbpmaxInstallColormap;
  385.     pScreen->UninstallColormap = cfbpmaxUninstallColormap;
  386.     pScreen->ListInstalledColormaps = cfbpmaxListInstalledColormaps;
  387.  
  388.     if (!cfbScreenInit(pScreen, info->bitmap, FRAMEWIDTH,
  389.             FRAMEHEIGHT, dpix, dpiy, FRAMEWIDTH, class, FRAMEWIDTH) ||
  390.     !cfbCreateDefColormap (pScreen))
  391.     {
  392.     close (fdPM);
  393.     return FALSE;
  394.     }
  395.     return TRUE;
  396. }
  397.  
  398. cfbpmaxPixelError(index)
  399. int index;
  400. {
  401.     ErrorF("Only 0 through 255 are acceptable pixels for device %d\n", index);
  402. }
  403. /* Totally bogus.  This procedure and data should be in the screen structure,
  404.    but devPriv is used extensively for the pointer to the screen bits.  There
  405.    is no screenPriv field. ||| */
  406.  
  407. unsigned int
  408. cfbpmaxSetPlaneMask(planemask)
  409.     unsigned int planemask;
  410. {
  411.     static unsigned int currentmask = ~0;
  412.     unsigned int result;
  413.  
  414.     result = currentmask;
  415.     currentmask = *(info->planemask) = planemask;
  416.     return result;
  417. }
  418.  
  419. static void
  420. ChangeLED(led, on)
  421.     int led;
  422.     Bool on ;
  423. {
  424.     struct pm_kpcmd ioc;
  425.  
  426.     switch (led) {
  427.        case 1:
  428.           ioc.par[0] = LED_1;
  429.           break;
  430.        case 2:
  431.           ioc.par[0] = LED_2;
  432.           break;
  433.        case 3:
  434.           /* the keyboard's LED_3 is the Lock LED, which the server owns.
  435.              So the user's LED #3 maps to the keyboard's LED_4. */
  436.           ioc.par[0] = LED_4;
  437.           break;
  438.        default:
  439.           return;   /* out-of-range LED value */
  440.           }
  441.  
  442.     ioc.cmd = on ? LK_LED_ENABLE : LK_LED_DISABLE;
  443.     ioc.par[1] = 0;
  444.     ioc.nbytes = 1;
  445.     ioctl(fdPM, QIOCKPCMD, &ioc);
  446. }
  447.  
  448.  
  449. static void
  450. cfbpmaxClick(click)
  451.     int         click;
  452. {
  453. #define LK_ENABLE_CLICK 0x1b    /* enable keyclick / set volume    */
  454. #define LK_DISABLE_CLICK 0x99    /* disable keyclick entirely    */
  455. #define LK_ENABLE_BELL 0x23    /* enable bell / set volume     */
  456.  
  457.     struct pm_kpcmd ioc;
  458.  
  459.     if (click == 0)    /* turn click off */
  460.     {
  461.     ioc.nbytes = 0;
  462.     ioc.cmd = LK_DISABLE_CLICK;
  463.     ioctl(fdPM, QIOCKPCMD, &ioc);
  464.     }
  465.     else 
  466.     {
  467.         int volume;
  468.  
  469.         volume = 7 - ((click / 14) & 7);
  470.     ioc.nbytes = 1;
  471.     ioc.cmd = LK_ENABLE_CLICK;
  472.     ioc.par[0] = volume;
  473.     ioctl(fdPM, QIOCKPCMD, &ioc);
  474.     }
  475. #undef LK_ENABLE_CLICK 
  476. #undef LK_DISABLE_CLICK
  477. #undef LK_ENABLE_BELL 
  478.  
  479. }
  480.  
  481. static void
  482. cfbpmaxChangeKeyboardControl(device, ctrl)
  483.     DevicePtr device;
  484.     KeybdCtrl *ctrl;
  485. {
  486.     int i;
  487.  
  488.     cfbpmaxClick(ctrl->click);
  489.  
  490.     /* ctrl->bell: the DIX layer handles the base volume for the bell */
  491.     
  492.     /* ctrl->bell_pitch: as far as I can tell, you can't set this on lk201 */
  493.  
  494.     /* ctrl->bell_duration: as far as I can tell, you can't set this  */
  495.  
  496.     /* LEDs */
  497.     for (i=1; i<=MAX_LED; i++)
  498.         ChangeLED(i, (ctrl->leds & (1 << (i-1))));
  499.  
  500.     /* ctrl->autoRepeat: I'm turning it all on or all off.  */
  501.  
  502.     SetLKAutoRepeat(ctrl->autoRepeat);
  503. }
  504.  
  505. static void
  506. cfbpmaxBell(loud, pDevice)
  507.     int loud;
  508.     DevicePtr pDevice;
  509. {
  510.     struct pm_kpcmd ioc;
  511.  
  512. /* the lk201 volume is between 7 (quiet but audible) and 0 (loud) */
  513.     loud = 7 - ((loud / 14) & 7);
  514.     ioc.nbytes = 1;
  515.     ioc.cmd = LK_BELL_ENABLE;
  516.     ioc.par[0] = loud;
  517.     ioctl(fdPM, QIOCKPCMD, &ioc);
  518.  
  519.     ioc.nbytes = 0;
  520.     ioc.cmd = LK_RING_BELL;
  521.     ioctl(fdPM, QIOCKPCMD, &ioc);
  522. }
  523.  
  524. /*
  525.  * These serve protocol requests, setting/getting acceleration and threshold.
  526.  * X10 analog is "SetMouseCharacteristics".
  527.  */
  528. static void
  529. cfbpmaxChangePointerControl(device, ctrl)
  530.     DevicePtr device;
  531.     PtrCtrl   *ctrl;
  532. {
  533.     info->mthreshold = ctrl->threshold;
  534.     if (!(info->mscale = ctrl->num / ctrl->den))
  535.     info->mscale = 1;    /* watch for den > num */
  536. }
  537.  
  538. static int
  539. cfbpmaxGetMotionEvents(pDevice, buff, start, stop)
  540.     CARD32 start, stop;
  541.     DevicePtr pDevice;
  542.     xTimecoord *buff;
  543. {
  544.     int     count = 0;
  545.     int     tcFirst = queue->tcNext;
  546.     int     tcLast = (tcFirst) ? tcFirst - 1 : queue->tcSize - 1;
  547.     register    pmTimeCoord * tcs;
  548.     int     i;
  549.  
  550.     for (i = tcFirst;; i++) {
  551.     if (i = queue->tcSize)
  552.         i = 0;
  553.     tcs = &queue->tcs[i];
  554.     if ((start <= tcs->time) && (tcs->time <= stop)) {
  555.         buff[count].time = tcs->time;
  556.         buff[count].x = tcs->x;
  557.         buff[count].y = tcs->y;
  558.         count++;
  559.     }
  560.     if (i == tcLast)
  561.         return count;
  562.     }
  563. }
  564.  
  565. int
  566. cfbpmaxMouseProc(pDev, onoff, argc, argv)
  567.     DevicePtr pDev;
  568.     int onoff, argc;
  569.     char *argv[];
  570. {
  571.     int     i;
  572.     BYTE    map[4];
  573.  
  574.     switch (onoff)
  575.     {
  576.     case DEVICE_INIT: 
  577.         pmPointer = pDev;
  578.         pDev->devicePrivate = (pointer) &queue;
  579.         map[1] = 1;
  580.         map[2] = 2;
  581.         map[3] = 3;
  582.         InitPointerDeviceStruct(
  583.         pmPointer, map, 3, cfbpmaxGetMotionEvents,
  584.         cfbpmaxChangePointerControl, MOTION_BUFFER_SIZE);
  585.         SetInputCheck(&queue->eHead, &queue->eTail);
  586.         hotX = hotY = 0;    
  587.         break;
  588.     case DEVICE_ON: 
  589.         pDev->on = TRUE;
  590.         AddEnabledDevice(fdPM); 
  591.         break;
  592.     case DEVICE_OFF: 
  593.         pDev->on = FALSE;
  594.         RemoveEnabledDevice(fdPM);
  595.         break;
  596.     case DEVICE_CLOSE:
  597.         break;
  598.     }
  599.     return Success;
  600. }
  601.  
  602. #define LK_REPEAT_ON  0xe3
  603. #define LK_REPEAT_OFF 0xe1
  604.  
  605. int
  606. SetLKAutoRepeat (onoff)
  607.     Bool onoff;
  608. {
  609.     extern char *AutoRepeatLKMode();
  610.     extern char *UpDownLKMode();
  611.     
  612.     struct pm_kpcmd ioc;
  613.     register char  *divsets;
  614.     divsets = onoff ? (char *) AutoRepeatLKMode() : (char *) UpDownLKMode();
  615.     ioc.nbytes = 0;
  616.     while (ioc.cmd = *divsets++)
  617.     ioctl(fdPM, QIOCKPCMD, &ioc);
  618.     ioc.cmd = ((onoff > 0) ? LK_REPEAT_ON : LK_REPEAT_OFF);
  619.     return(ioctl(fdPM, QIOCKPCMD, &ioc));
  620. }
  621.  
  622. int
  623. cfbpmaxKeybdProc(pDev, onoff, argc, argv)
  624.     DevicePtr pDev;
  625.     int onoff, argc;
  626.     char *argv[];
  627. {
  628.     KeySymsRec keySyms;
  629.     CARD8 modMap[MAP_LENGTH];
  630.  
  631.     switch (onoff)
  632.     {
  633.     case DEVICE_INIT: 
  634. /* Note that keyclick is off by default.  The QDSS MIT server sets it
  635.    to 20 */    
  636.         pmKeyboard = pDev;
  637.         GetLK201Mappings( &keySyms, modMap);
  638.         InitKeyboardDeviceStruct(
  639.             pmKeyboard, &keySyms, modMap, cfbpmaxBell,
  640.             cfbpmaxChangeKeyboardControl);
  641.             cfbpmaxClick(0);     /* turn key click off */        
  642.         /* Free the key sym mapping space allocated by GetLK201Mappings. */
  643.         Xfree(keySyms.map);
  644.         break;
  645.     case DEVICE_ON: 
  646.         pDev->on = TRUE;
  647.         AddEnabledDevice(fdPM); 
  648.         break;
  649.     case DEVICE_OFF: 
  650.         pDev->on = FALSE;
  651.         RemoveEnabledDevice(fdPM);
  652.         break;
  653.     case DEVICE_CLOSE: 
  654.         break;
  655.     }
  656.     return Success;
  657. }
  658. /*
  659.  * The driver has been set up to put events in the queue that are identical
  660.  * in shape to the events that the DDX layer has to deliver to ProcessInput
  661.  * in DIX.
  662.  */
  663. extern int screenIsSaved;
  664.  
  665. void
  666. ProcessInputEvents()
  667. {
  668. #define DEVICE_KEYBOARD 2
  669.     xEvent x;
  670.     pmEvent e;
  671.     register int    i;
  672.  
  673.     i = queue->eHead;
  674.     while (i != queue->eTail)
  675.     {
  676.     e = *((pmEvent *)&queue->events[i]);
  677.     if (screenIsSaved == SCREEN_SAVER_ON)
  678.         SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
  679.     x.u.keyButtonPointer.rootX = e.x + hotX;
  680.     x.u.keyButtonPointer.rootY = e.y + hotY;
  681.     x.u.keyButtonPointer.time = lastEventTime = e.time;
  682.     x.u.u.detail = e.key;
  683.  
  684.     if (e.device == DEVICE_KEYBOARD)
  685.     {
  686.         switch (e.type)
  687.         {
  688.         case BUTTON_DOWN_TYPE: 
  689.             x.u.u.type = KeyPress;
  690.             (*pmKeyboard->processInputProc) (&x, pmKeyboard, 1);
  691.             break;
  692.         case BUTTON_UP_TYPE: 
  693.             x.u.u.type = KeyRelease;
  694.             (*pmKeyboard->processInputProc) (&x, pmKeyboard, 1);
  695.             break;
  696.         default:            /* hopefully BUTTON_RAW_TYPE */
  697.             ProcessLK201Input(&x, pmKeyboard);
  698.         }
  699.     }
  700.     else
  701.     {
  702.         switch (e.type)
  703.         {
  704.         case BUTTON_DOWN_TYPE: 
  705.             x.u.u.type = ButtonPress;
  706.             break;
  707.         case BUTTON_UP_TYPE: 
  708.             x.u.u.type = ButtonRelease;
  709.             break;
  710.         case MOTION_TYPE: 
  711.             x.u.u.type = MotionNotify;
  712.             break;
  713.         default: 
  714.             printf("Unknown input event = %d\n",e.type);
  715.             continue;
  716.         }
  717.         (*pmPointer->processInputProc) (&x, pmPointer, 1);
  718.     }
  719.     if (i == qLimit)
  720.         i = queue->eHead = 0;
  721.     else
  722.         i = ++queue->eHead;
  723.     }
  724. #undef DEVICE_KEYBOARD
  725. }
  726.  
  727. TimeSinceLastInputEvent()
  728. {
  729.     if (lastEventTime == 0)
  730.     lastEventTime = CURRENT_TIME;
  731.     return CURRENT_TIME -  lastEventTime;
  732. }
  733.  
  734. /*
  735.  * set the bounds in the device for this particular cursor
  736.  */
  737. static void
  738. cfbpmaxConstrainCursor( pScr, pBox)
  739.     ScreenPtr    pScr;
  740.     BoxPtr    pBox;
  741. {
  742.     cursorConstraint = *pBox;
  743.     if (info)
  744.     {
  745.     info->max_cur_x = pBox->x2 - hotX - 1;
  746.     info->max_cur_y = pBox->y2 - hotY - 1;
  747.     info->min_cur_x = pBox->x1 - hotX;
  748.     info->min_cur_y = pBox->y1 - hotY;
  749.     }
  750. }
  751.  
  752. Bool
  753. cfbpmaxSetCursorPosition( pScr, newx, newy, generateEvent)
  754.     ScreenPtr    pScr;
  755.     unsigned int    newx;
  756.     unsigned int    newy;
  757.     Bool        generateEvent;
  758. {
  759.     pmCursor pmCPos;
  760.     xEvent motion;
  761.  
  762.     pmCPos.x = newx - hotX;
  763.     pmCPos.y = newy - hotY;
  764.  
  765.     if (ioctl (fdPM, QIOCPMSTATE, &pmCPos) < 0) {
  766.     ErrorF ("error warping cursor\n");
  767.     return FALSE;
  768.     }
  769.  
  770.     if (generateEvent) {
  771.     if (queue->eHead != queue->eTail)
  772.         ProcessInputEvents ();
  773.     motion.u.keyButtonPointer.rootX = newx;
  774.     motion.u.keyButtonPointer.rootY = newy;
  775.     motion.u.keyButtonPointer.time = currentTime.milliseconds;
  776.     motion.u.u.type = MotionNotify;
  777.     (pmPointer->processInputProc)(&motion, pmPointer, 1);
  778.     }
  779.     return TRUE;
  780. }
  781.  
  782. static Bool
  783. cfbpmaxDisplayCursor( pScr, pCurs)
  784.     ScreenPtr    pScr;
  785.     CursorPtr    pCurs;
  786. {
  787.     register    int        i;
  788.     int        x, y;
  789.     unsigned    *pColors;
  790.  
  791.     /*
  792.      * load the cursor
  793.      */
  794.     if ((hotX != pCurs->bits->xhot) || (hotY != pCurs->bits->yhot))
  795.     {
  796.     x = mouse->x + hotX;
  797.     y = mouse->y + hotY;
  798.     hotX = pCurs->bits->xhot;
  799.     hotY = pCurs->bits->yhot;
  800.     cfbpmaxSetCursorPosition(pScr, x, y, FALSE);
  801.     cfbpmaxConstrainCursor(pScr, &cursorConstraint);
  802.         /* to update constraints in driver */
  803.     }
  804.     if ( ioctl( fdPM, QIOWCURSOR, pCurs->devPriv[ pScr->myNum]) < 0)
  805.     {
  806.     ErrorF( "error loading bits of new cursor\n");
  807.         return FALSE;
  808.     }
  809.  
  810.  
  811.     /* pick the background color */
  812.     cursColors[3] = pCurs->backRed;
  813.     cursColors[4] = pCurs->backGreen;
  814.     cursColors[5] = pCurs->backBlue;
  815.  
  816.     /* pick the foreground color */
  817.     cursColors[0] = pCurs->foreRed;
  818.     cursColors[1] = pCurs->foreGreen;
  819.     cursColors[2] = pCurs->foreBlue;
  820.  
  821.     /*
  822.     for (i=0;i<6;i++)
  823.     printf ("colors[%d]= %d\n", i, cursColors[i]);
  824.     */
  825.     pColors = &cursColors[0];
  826.     if ( ioctl( fdPM, QIOWCURSORCOLOR, cursColors) < 0)
  827.     {
  828.     ErrorF( "error writing colors of new cursor\n");
  829.         return FALSE;
  830.     }
  831.  
  832.     return (TRUE);
  833.  
  834. }
  835.  
  836. static void
  837. cfbpmaxRecolorCursor (pScr, pCurs, displayed)
  838.     ScreenPtr    pScr;
  839.     CursorPtr    pCurs;
  840.     Bool    displayed;
  841. {
  842.     unsigned    *pColors;
  843.  
  844.     if (!displayed)
  845.     return;
  846.  
  847.     /* pick the background color */
  848.     cursColors[3] = pCurs->backRed;
  849.     cursColors[4] = pCurs->backGreen;
  850.     cursColors[5] = pCurs->backBlue;
  851.  
  852.     /* pick the foreground color */
  853.     cursColors[0] = pCurs->foreRed;
  854.     cursColors[1] = pCurs->foreGreen;
  855.     cursColors[2] = pCurs->foreBlue;
  856.  
  857.     /*
  858.     for (i=0;i<6;i++)
  859.     printf ("colors[%d]= %d\n", i, cursColors[i]);
  860.     */
  861.     pColors = &cursColors[0];
  862.     if ( ioctl( fdPM, QIOWCURSORCOLOR, &pColors) < 0)
  863.     {
  864.     ErrorF( "error writing colors of new cursor\n");
  865.         return;
  866.     }
  867.  
  868.     return;
  869. }
  870.  
  871. static Bool
  872. cfbpmaxRealizeCursor( pScr, pCurs)
  873.     ScreenPtr    pScr;
  874.     CursorPtr    pCurs;    /* a SERVER-DEPENDENT cursor */
  875. {
  876.     int    forecolor = 0;
  877.     int    backcolor = ~forecolor;
  878.     register short    *a, *b;    /* vaxstar-defined */
  879.     register int *    mask;    /* server-defined */
  880.     register int *    src;    /* server-defined */
  881.     int        i;
  882.     int        cursorBytes = 32*sizeof(short);
  883.     int        lastRow = ((pCurs->bits->height < 16) ? pCurs->bits->height : 16);
  884.     register unsigned short widthmask = (1<<pCurs->bits->width)-1;
  885.                 /* used to mask off beyond the edge of the
  886.                    real mask and source bits
  887.                 */
  888.  
  889.     pCurs->devPriv[ pScr->myNum] = (pointer)Xalloc(cursorBytes);
  890.     bzero((char *)pCurs->devPriv[ pScr->myNum], cursorBytes);
  891.  
  892.     /*
  893.      * munge the SERVER-DEPENDENT, device-independent cursor bits into
  894.      * what the device wants, which is 32 contiguous shorts.
  895.      *
  896.      * cursor hardware has "A" and "B" bitmaps
  897.      * logic table is:
  898.      *
  899.      *        A    B    cursor
  900.      *
  901.      *        0    0    transparent
  902.      *        1    0    xor (not used)
  903.      *        0    1    black
  904.      *        1    1    white
  905.      */
  906.  
  907.     /*
  908.      * "a" bitmap = image 
  909.      */
  910.     /*
  911.      * "b" bitmap can be same as "mask", providing "a" is never on when
  912.      *  "b" is off.
  913.      */
  914.     for ( i=0,
  915.       a = (short *)pCurs->devPriv[pScr->myNum],
  916.       b = ((short *)pCurs->devPriv[pScr->myNum]) + 16,
  917.     /* XXX assumes server bitmap pad is size of int, 
  918.        and cursor is < 32 bits wide */
  919.       src = (int *)pCurs->bits->source,
  920.       mask = (int *)pCurs->bits->mask;
  921.  
  922.       i < lastRow;
  923.  
  924.       i++, a++, b++, src++, mask++)
  925.     {
  926.     *a = ((*src & forecolor) | (~*src & backcolor)) & *mask;
  927.     *b = *mask;
  928.     *a &= widthmask;
  929.     *b &= widthmask;
  930.     }
  931.     return TRUE;
  932. }
  933.  
  934. static Bool
  935. cfbpmaxUnrealizeCursor( pScr, pCurs)
  936.     ScreenPtr    pScr;
  937.     CursorPtr    pCurs;
  938. {
  939.     Xfree( pCurs->devPriv[ pScr->myNum]);
  940.     return TRUE;
  941. }
  942.  
  943. /*
  944.  * pm cursor top-left corner can now go to negative coordinates
  945.  */
  946. static void
  947. cfbpmaxCursorLimits( pScr, pCurs, pHotBox, pPhysBox)
  948.     ScreenPtr    pScr;
  949.     CursorPtr    pCurs;
  950.     BoxPtr    pHotBox;
  951.     BoxPtr    pPhysBox;    /* return value */
  952. {
  953.     pPhysBox->x1 = max( pHotBox->x1, cursorRange.x1 + (int) pCurs->bits->xhot);
  954.     pPhysBox->y1 = max( pHotBox->y1, cursorRange.y1 + (int) pCurs->bits->yhot);
  955.     pPhysBox->x2 = min( pHotBox->x2, cursorRange.x2 + 1);
  956.     pPhysBox->y2 = min( pHotBox->y2, cursorRange.y2 + 1);
  957. }
  958.  
  959. static void
  960. cfbpmaxPointerNonInterestBox( pScr, pBox)
  961.     ScreenPtr    pScr;
  962.     BoxPtr    pBox;
  963. {
  964.     info->mbox.bottom = pBox->y2;
  965.     info->mbox.top = pBox->y1;
  966.     info->mbox.left = pBox->x1;
  967.     info->mbox.right = pBox->x2;
  968. }
  969.  
  970. static void
  971. cfbpmaxQueryBestSize(class, pwidth, pheight)
  972.     int class;
  973.     short *pwidth;
  974.     short *pheight;
  975. {
  976.     unsigned width, test;
  977.  
  978.     if (*pwidth > 0)
  979.     {
  980.       switch(class)
  981.       {
  982.         case CursorShape:
  983.       *pwidth = 16;
  984.       *pheight = 16;
  985.       break;
  986.         case TileShape:
  987.         case StippleShape:
  988.       width = *pwidth;
  989.       /* Return the closes power of two not less than what they gave me */
  990.       test = 0x80000000;
  991.       /* Find the highest 1 bit in the width given */
  992.       while(!(test & width))
  993.          test >>= 1;
  994.       /* If their number is greater than that, bump up to the next
  995.        *  power of two */
  996.       if((test - 1) & width)
  997.          test <<= 1;
  998.       *pwidth = test;
  999.       /* We don't care what height they use */
  1000.       break;
  1001.        }
  1002.     }
  1003. }
  1004.  
  1005. Bool
  1006. mfbScreenClose(pScreen)
  1007.     register ScreenPtr pScreen;
  1008. {
  1009.  
  1010.     if (pScreen->allowedDepths)
  1011.     {
  1012.     if (pScreen->allowedDepths->vids)
  1013.         Xfree(pScreen->allowedDepths->vids);
  1014.  
  1015.     Xfree(pScreen->allowedDepths);
  1016.     }
  1017.  
  1018.     /*  pScreen->visuals does not need to be freed here, since it is added as
  1019.     a resource in "mfbScreenInit" and is freed with the rest of the 
  1020.     resources. */
  1021.  
  1022.     if(pScreen->devPrivate)
  1023.     Xfree(pScreen->devPrivate);
  1024.  
  1025.  /* Does pScreen->devPrivate->devPrivate have to be freed since it's a bitmap?
  1026.     but I don't know where or how it is allocated. It may be static. */
  1027.  
  1028.     return TRUE;
  1029. }
  1030.  
  1031. void
  1032. SetLockLED (on)
  1033.     Bool on;
  1034. {
  1035.     struct pm_kpcmd ioc;
  1036.     ioc.cmd = on ? LK_LED_ENABLE : LK_LED_DISABLE;
  1037.     ioc.par[0] = LED_3;
  1038.     ioc.par[1] = 0;
  1039.     ioc.nbytes = 1;
  1040.     ioctl(fdPM, QIOCKPCMD, &ioc);
  1041. }
  1042.  
  1043. /*
  1044.  * DDX - specific abort routine.  Called by AbortServer().
  1045.  */
  1046. void
  1047. AbortDDX()
  1048. {
  1049. }
  1050.  
  1051. /* Called by GiveUp(). */
  1052. void
  1053. ddxGiveUp()
  1054. {
  1055. }
  1056.  
  1057. int
  1058. ddxProcessArgument (argc, argv, i)
  1059.     int argc;
  1060.     char *argv[];
  1061.     int i;
  1062. {
  1063.     int            argind=i;
  1064.     int            skip;
  1065.     static int        Once=0;
  1066.     void        ddxUseMsg();
  1067.  
  1068.     skip = 0;
  1069.     if (!Once)
  1070.     {
  1071.         blackValue = NULL;
  1072.         whiteValue = NULL;
  1073.     Once = 1;
  1074.     }
  1075.  
  1076.     if (strcmp( argv[argind], "-dpix") == 0)
  1077.     {
  1078.     if (++argind < argc)
  1079.     {
  1080.         dpix = atoi(argv[argind]);
  1081.         skip = 2;
  1082.     }
  1083.     else
  1084.         return 0;    /* failed to parse */
  1085.     }
  1086.     else if (strcmp( argv[argind], "-dpiy") == 0)
  1087.     {
  1088.     if (++argind < argc)
  1089.     {
  1090.         dpiy = atoi(argv[argind]);
  1091.         skip = 2;
  1092.     }
  1093.     else
  1094.         return 0;
  1095.     }
  1096.     else if (strcmp( argv[argind], "-dpi") == 0)
  1097.     {
  1098.     if (++argind < argc)
  1099.     {
  1100.         dpi = atoi(argv[argind]);
  1101.         dpix = dpi;
  1102.         dpiy = dpi;
  1103.         skip = 2;
  1104.     }
  1105.     else
  1106.         return 0;
  1107.     }
  1108.     else 
  1109.     if(strcmp(argv[argind], "-bp") == 0 )
  1110.     {
  1111.         if(++argind < argc)
  1112.         {
  1113.         blackValue = argv[argind];
  1114.         skip = 2;
  1115.         }
  1116.         else
  1117.             return 0;
  1118.     }
  1119.     else
  1120.     if(strcmp(argv[argind], "-wp") == 0 )
  1121.     {
  1122.         if(++argind < argc)
  1123.         {
  1124.         whiteValue = argv[argind];
  1125.         skip = 2;
  1126.         }
  1127.         else
  1128.             return 0;
  1129.     }
  1130.     else
  1131.     if (strcmp(argv[argind], "-class") == 0 )
  1132.     {
  1133.         if(++argind < argc)
  1134.         {
  1135.         class = ParseClass(argv[argind]);
  1136.         if (class == NoSuchClass)
  1137.             return 0;
  1138.         skip = 2;
  1139.         }
  1140.         else
  1141.             return 0;
  1142.     }
  1143.     return skip;
  1144. }
  1145.  
  1146. void
  1147. ddxUseMsg()
  1148. {
  1149.     ErrorF ("\n");
  1150.     ErrorF ("\n");
  1151.     ErrorF ("Device Dependent Usage\n");
  1152.     ErrorF ("\n");
  1153.     ErrorF ("-dpix <n>          Dots per inch, x coordinate\n");
  1154.     ErrorF ("-dpiy <n>          Dots per inch, y coordinate\n");
  1155.     ErrorF ("-dpi <n>           Dots per inch, x and y coordinates\n");
  1156.     ErrorF ("                   (overrides -dpix and -dpiy above)\n");
  1157.     ErrorF ("-bp #XXX           color for BlackPixel for screen\n");
  1158.     ErrorF ("-wp #XXX           color for WhitePixel for screen\n");
  1159.     ErrorF ("-class <classname> type of Visual for root window\n");
  1160.     ErrorF ("       one of StaticGray, StaticColor, PseudoColor,\n");
  1161.     ErrorF ("       GrayScale, or even TrueColor!\n");
  1162. }
  1163.